.\" Copyright (c) 2014-2019 Julien Nadeau Carriere <vedge@csoft.net>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\" 
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
.\" (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd April 14, 2014
.Dt AG_EVENTLOOP 3
.Os
.ds vT Agar API Reference
.ds oS Agar 1.5
.Sh NAME
.Nm AG_EventLoop
.Nd agar low-level event loop
.Sh SYNOPSIS
.Bd -literal
#include <agar/core.h>
.Ed
.Sh DESCRIPTION
The
.Nm
routine loops, continually checking for low-level events and processing them.
Its operation is governed by a registered set of
.Em Event Sinks
which determine the type of low-level events to monitor, and the procedures
to invoke in order to handle them.
.Pp
The most common type of low-level events are:
.Pp
.Bl -enum -compact
.It
Activity on a socket or file descriptor.
.It
Expiration of a timer.
.It
Kernel-event notifications (e.g.,
.Xr kqueue 2
events).
This includes filesystem events and process monitoring.
.El
.Pp
Concurrent instances of
.Fn AG_EventLoop
are allowed in multithreaded builds.
In threaded builds, event sinks are associated with running thread at
the time of creation (in thread-local storage).
.Sh MAIN INTERFACE
.nr nS 1
.Ft "int"
.Fn AG_EventLoop "void"
.Pp
.Ft void
.Fn AG_Terminate "int exitCode"
.Pp
.Ft void
.Fn AG_TerminateEv "AG_Event *event"
.Pp
.nr nS 0
.Fn AG_EventLoop
blocks the current thread, waiting for low-level events, and processing them
until termination is requested.
Its operation is governed by the registered set of event sinks.
.Pp
The
.Fn AG_Terminate
function requests termination of the event loop associated with the
current thread.
If the current thread is the main thread,
.Fn AG_Terminate
will terminate the application with
.Fa exitCode
as return code.
The
.Fn AG_TerminateEv
variant accepts an
.Ft AG_Event
style argument instead of an
.Ft int
for the exit code.
.Sh EVENT SINKS
.\" MANLINK(AG_EventSink)
.nr nS 1
.Ft "AG_EventSink *"
.Fn AG_AddEventSink "enum ag_event_sink_type type" "int ident" "Uint flags" "AG_EventSinkFn fn" "const char *fnArgs"
.Pp
.Ft "void"
.Fn AG_DelEventSink "AG_EventSink *sink"
.Pp
.Ft "void"
.Fn AG_DelEventsSinkByIdent "enum ag_event_sink_type type" "int ident" "Uint flags"
.Pp
.Ft "AG_EventSink *"
.Fn AG_AddEventPrologue "AG_EventSinkFn fn" "const char *fnArgs" "..."
.Pp
.Ft "AG_EventSink *"
.Fn AG_AddEventEpilogue "AG_EventSinkFn fn" "const char *fnArgs" "..."
.Pp
.Ft "AG_EventSink *"
.Fn AG_AddEventSpinner "AG_EventSinkFn fn" "const char *fnArgs" "..."
.Pp
.Ft "void"
.Fn AG_DelEventPrologue "AG_EventSink *sink"
.Pp
.Ft "void"
.Fn AG_DelEventEpilogue "AG_EventSink *sink"
.Pp
.Ft "void"
.Fn AG_DelEventSpinner "AG_EventSink *sink"
.nr nS 0
.Pp
The
.Fn AG_AddEventSink
routine creates a new event sink under the current thread, and returns
a pointer to a newly-allocated
.Ft AG_EventSink
structure.
The
.Fa type
argument may be one of:
.Bl -tag -width "AG_SINK_PROCEVENT "
.It Dv AG_SINK_READ
Data is available for reading on file referenced by
.Fa ident .
.It Dv AG_SINK_WRITE
Data is available for writing on file referenced by
.Fa ident .
.It Dv AG_SINK_FSEVENT
A filesystem event has occurred on the file/directory
referenced by
.Fa ident .
The type of event is specified in
.Fa flags
(see
.Sx FILESYSTEM EVENTS
for the accepted flags).
.It Dv AG_SINK_PROCEVENT
An event has occurred on the monitored process
.Fa ident .
The type of event is specified in
.Fa flags
(see
.Sx PROCESS EVENTS
below).
.El
.Pp
The
.Fn AG_DelEventSink
function destroys the specified event sink.
The
.Fn AG_DelEventSinksByIdent
function destroys all event sinks with matching
.Fa ident
and
.Fa flags.
.Pp
The
.Fn AG_AddEventPrologue
function registers a callback routine to be invoked once at the
start of
.Fn AG_EventLoop .
.Fn AG_AddEventEpilogue
registers a callback routine to be invoked on exit, before
.Fn AG_EventLoop
returns.
.Fn AG_DelEventEpilogue
and
.Fn AG_DelEventPrologue
destroy the specified epilogue/prologue routine.
.Pp
The
.Fn AG_AddEventSpinner
routine registers a "spinner" callback routine.
Spinner routines are invoked repeatedly and unconditionally by
.Fn AG_EventLoop ,
until the event loop terminates, or
.Fn AG_DelEventSpinner
is invoked.
.Sh FILESYSTEM EVENTS
Acceptable
.Fa flags
for the
.Dv AG_SINK_FSEVENT
event sink include:
.Pp
.Bl -tag -width "AG_FSEVENT_DELETE " -compact
.It Dv AG_FSEVENT_DELETE
The file has been deleted.
.It Dv AG_FSEVENT_WRITE
The file was written to.
.It Dv AG_FSEVENT_EXTEND
The file was extended in size.
.It Dv AG_FSEVENT_ATTRIB
File attributes have been changed.
.It Dv AG_FSEVENT_LINK
The link count on the file has changed.
.It Dv AG_FSEVENT_RENAME
The referenced file has been renamed.
.It Dv AG_FSEVENT_REVOKE
Filesystem has unmount, or
.Xr revoke 2
called.
.El
.Sh PROCESS EVENTS
Acceptable
.Fa flags
for the
.Dv AG_SINK_PROCEVENT
event sink include:
.Pp
.Bl -tag -width "AG_PROCEVENT_EXIT " -compact
.It Dv AG_PROCEVENT_EXIT
Monitored process has exited.
.It Dv AG_PROCEVENT_FORK
Monitored process has called
.Xr fork 2 .
.It Dv AG_PROCEVENT_EXEC
Monitored process has called
.Xr exec 3 .
.El
.Sh EXAMPLES
Agar's X11 driver
.Xr AG_DriverGLX 3
sets up an event sink of type
.Dv AG_SINK_READ
in order to receive events from the X file descriptor.
.Pp
For directory listings to refresh automatically on platforms which offer
filesystem monitoring capabilities,
.Xr AG_FileDlg 3
uses
.Dv AG_SINK_FSEVENT .
.Pp
The
.Xr AG_ConsoleOpenFile 3
feature of
.Xr AG_Console 3
sets up an event sink of type
.Dv AG_SINK_READ
to monitor changes on a file or stream.
.Pp
The
.Xr agardb 1
debugger uses
.Dv AG_SINK_PROCEVENT
to monitor events related to processes being debugged.
.Sh SEE ALSO
.Xr AG_CustomEventLoop 3 ,
.Xr AG_Event 3 ,
.Xr AG_Intro 3 ,
.Xr poll 2 ,
.Xr select 2 ,
.Xr kqueue 2
.Sh HISTORY
The
.Nm
call first appeared in Agar 1.0.
Event sinks first appeared in Agar 1.5.0.
